package cn.iocoder.yudao.module.trade.order.service;

import cn.iocoder.yudao.framework.business.order.pojo.vo.OrderSubmitVO;
import cn.iocoder.yudao.module.api.trade.order.dto.GiftTradeOrderSaveDTO;
import cn.iocoder.yudao.module.api.trade.order.dto.TradeOrderArriveDTO;
import cn.iocoder.yudao.module.api.trade.order.dto.TradeOrderDeliveryDTO;
import cn.iocoder.yudao.module.trade.order.dal.dataobject.TradeOrderDO;
import cn.iocoder.yudao.module.trade.order.vo.*;
import jakarta.validation.constraints.NotNull;

import java.util.List;

/**
 * 交易订单【写】ServiceImpl 实现类
 *
 * @author LeeYan9
 * @since 2022-08-26
 */
public interface TradeOrderUpdateService {

    // =================== Order ===================

    /**
     * 获得订单结算信息
     *
     * @param userId          登录用户
     * @param settlementReqVO 订单结算请求
     * @return 订单结算结果
     */
    AppTradeOrderSettlementRespVO settlementOrder(Long userId, AppTradeOrderSettlementReqVO settlementReqVO);

    /**
     * 【系统】创建赠品订单
     */
    OrderSubmitVO createGiftTradeOrder(Long userId, GiftTradeOrderSaveDTO saveDTO);

    /**
     * 【用户】创建交易订单
     *
     * @param userId      登录用户
     * @param createReqVO 创建交易订单请求模型
     * @return 交易订单的
     */
    TradeOrderDO createOrder(Long userId, AppTradeOrderCreateReqVO createReqVO);

    /**
     * 更新交易订单已过期
     *
     * @param tradeNo         交易单号
     */
    void updateOrderExpired(String tradeNo);

    /**
     * 更新交易订单已支付
     *
     * @param tradeNo 交易单号
     * @param payNo 支付单号
     */
    void updateOrderPaid(String tradeNo, String payNo);

    /**
     * 更新交易订单已退款
     *
     * @param no         售后单号
     */
    void updateOrderRefunded(String no);

    /**
     * 同步订单的支付状态
     * 1. Quietly 表示，即使同步失败，也不会抛出异常
     * 2. 什么时候回出现异常？因为是主动同步，可能和支付模块的回调通知 {@link #updateOrderPaid} 存在并发冲突，导致抛出异常
     *
     * @param tradeNo         交易单号
     */
    void syncOrderPayStatusQuietly(String tradeNo);

    /**
     * 【管理员】发货交易订单
     *
     * @param dto 发货请求
     */
    void deliveryOrder(TradeOrderDeliveryDTO dto);

    /**
     * 【商家】交易订单发货
     *
     * @param shopId        店铺编号
     * @param dto 发货请求
     */
    void deliveryOrder(Long shopId, TradeOrderDeliveryDTO dto);

    /**
     * 【商家】交易订单接单
     *
     * @param shopId        店铺编号
     * @param id     订单编号
     */
    void acceptOrder(Long shopId, Long id);

    /**
     * 【商家】交易订单出餐
     *
     * @param shopId        店铺编号
     * @param id     订单编号
     */
    void packOrder(Long shopId, Long id);

    /**
     * 【配送员】交易订单取餐
     *
     * @param userId        用户编号
     * @param id     订单编号
     */
    void pickupOrderByRider(Long userId, Long id);

    /**
     * 【用户】交易订单收货
     *
     * @param userId 用户编号
     * @param id     订单编号
     */
    void receiveOrderByBuyer(Long userId, Long id);

    /**
     * 【配送员】交易订单送达
     *
     * @param userId 用户编号
     * @param dto     送达请求
     */
    void receiveOrderByRider(Long userId, TradeOrderArriveDTO dto);

    /**
     * 【系统】交易订单自动收货
     *
     * @return 收货数量
     */
    int receiveOrderBySystem();

    /**
     * 【用户】取消交易订单
     *
     * @param userId 用户编号
     * @param id     订单编号
     */
    void cancelOrderByBuyer(Long userId, Long id);

    /**
     * 【系统】自动取消订单
     *
     * @return 取消数量
     */
    int cancelOrderBySystem();

    /**
     * 【用户】删除订单
     *
     * @param userId 用户编号
     * @param id     订单编号
     */
    void deleteOrder(Long userId, Long id);

    /**
     * 【管理员】交易订单备注
     *
     * @param reqVO 请求
     */
    void updateOrderRemark(TradeOrderRemarkReqVO reqVO);

    /**
     * 【管理员】调整价格
     *
     * @param reqVO 请求
     */
    void updateOrderPrice(TradeOrderUpdatePriceReqVO reqVO);

    /**
     * 【管理员】调整地址
     *
     * @param reqVO 请求
     */
    void updateOrderAddress(TradeOrderUpdateAddressReqVO reqVO);

    /**
     * 【管理员】核销订单
     *
     * @param adminUserId 管理员编号
     * @param id 订单编号
     */
    void verifyOrderByAdmin(Long adminUserId, Long id);

    /**
     * 【管理员】核销订单
     *
     * @param adminUserId 管理员编号
     * @param verifyCode 核销码
     */
    void verifyOrderByAdmin(Long adminUserId, String verifyCode);

    /**
     * 核销订单
     *
     * @param memberUserId 用户编号
     * @param verifyCode 核销码
     */
    void verifyOrderByMember(Long memberUserId, String verifyCode);

    /**
     * 根据核销码查询订单
     *
     * @param userId 用户编号
     * @param userType 用户类型
     * @param verifyCode 核销码
     */
    TradeOrderDO getByVerifyCode(Long userId, Integer userType, String verifyCode);

    // =================== Order Item ===================

    /**
     * 当售后申请后，更新交易订单项的售后状态
     *
     * @param id 交易订单项编号
     * @param orderId 交易订单编号
     * @param afterSaleId 售后单编号
     */
    void updateOrderItemWhenAfterSaleCreate(@NotNull Long id, @NotNull Long orderId, @NotNull Long afterSaleId);

    /**
     * 当售后进行中，更新交易订单项的售后状态
     *
     * @param id 交易订单项编号
     * @param orderId 交易订单编号
     */
    void updateOrderItemWhenAfterSaleDoing(@NotNull Long id, @NotNull Long orderId, Integer oldStatus, Integer newStatus);

    /**
     * 当售后完成后，更新交易订单项的售后状态
     *
     * @param id 交易订单项编号
     * @param orderId 交易订单编号
     * @param refundPrice 退款金额
     */
    void updateOrderItemWhenAfterSaleSuccess(@NotNull Long id, @NotNull Long orderId, @NotNull Integer refundPrice);

    /**
     * 当售后取消（用户取消、管理员驳回、管理员拒绝收货）后，更新交易订单项的售后状态
     *
     * @param id 交易订单项编号
     * @param orderId 交易订单编号
     */
    void updateOrderItemWhenAfterSaleCancel(@NotNull Long id, @NotNull Long orderId);

    /**
     * 【用户】创建订单的评论
     *
     * @param userId      用户编号
     * @param createReqVO 创建请求
     * @return 得到评价 id
     */
    Long createOrderCommentByMember(Long userId, AppTradeOrderEvaluationCreateReqVO createReqVO);

    /**
     * 【用户】创建订单项的评论
     *
     * @param userId      用户编号
     * @param createReqVO 创建请求
     * @return 得到评价 id
     */
    Long createOrderItemCommentByMember(Long userId, AppTradeOrderItemEvaluationCreateReqVO createReqVO);

    /**
     * 【系统】创建订单项的评论
     *
     * @return 被评论的订单数
     */
    int createOrderItemCommentBySystem();

    /**
     * 更新拼团相关信息到订单
     *
     * @param orderId             订单编号
     * @param activityId          拼团活动编号
     * @param combinationRecordId 拼团记录编号
     * @param headId              团长编号
     */
    void updateOrderCombinationInfo(Long orderId, Long activityId, Long combinationRecordId, Long headId);

    /**
     * 取消支付订单
     *
     * @param userId  用户编号
     * @param orderId 订单编号
     * @param cancelType 取消类型
     */
    void cancelPaidOrderByBuyer(Long userId, Long orderId, Integer cancelType);

    /**
     * 商家取消支付订单
     *
     * @param orderId 订单编号
     */
    void cancelPaidOrderBySeller(Long orderId);

    /**
     * 更新下单赠送的优惠券编号到订单
     *
     * @param userId        用户编号
     * @param orderId       订单编号
     * @param giveCouponIds 赠送的优惠券编号列表
     */
    void updateOrderGiveCouponIds(Long userId, Long orderId, List<Long> giveCouponIds);

}
